import { Engine } from "../engine";
import { Util } from "../../utils/util";
import { OrderUtil } from "../../utils/orderUtil";
import { DocBase } from "../common/docBase";
import { DocType, CommonOrderStatus, ProgressState,OrderSortType } from "../common/docDefinition";
import { TargetObject, TargetObjectType } from "../targetOrg/targetObject";
import { PendingPaymentOrder } from "./pendingPaymentOrder";
import { FundAccount } from "./fundAccount";
import { CsFundDouble } from "../common/csFundDouble";
import { DateUtil } from "../../utils/dateUtil";
import { ReceiveFundType, PaymentFundType, PaymentOverFlowHandleMethod } from "../common/fundDefinition";
import { FunctionPermissionDefinition } from "../platform/functionPermissionDefinition";


export class FundOrderFilter {
    /**
     * @param {Object} [options]
     * @param {string} [options.id] - 单号
     * @param {string} [options.title] - 单据标题
     * @param {string} [options.targetObjName] - 往来单位名称
     * @param {string} [options.targetObjId] - 往来单位ID
     * @param {Date} [options.startDate] - 开始时间
     * @param {Date} [options.endDate] - 结束时间
     * @param {CommonOrderStatus} [options.status] - 状态
     * @param {ReceiveFundType} [options.receiveFundType] - 付款单类型
     * @param {PaymentFundType} [options.paymentFundType] - 付款单类型
     * @param {OrderSortType} [options.sortType] - 排序方式
     * @param {string} [options.storeId] - 门店ID
     * @param {boolean} [options.excludeTriggeredFundOrder] - 是否排除业务单据触发的资金单据
     */
    constructor({
        id = null,
        title = null,
        targetObjId = null,
        targetObjName = null,
        startDate = null,
        endDate = null,
        status = null,
        receiveFundType = null,
        paymentFundType = null,
        sortType = OrderSortType.CreateTime.code,
        storeId = null,
        excludeTriggeredFundOrder = null
    } = {}) {
        this.id = id;
        this.title = title;
        this.targetObjId = targetObjId;
        this.targetObjName = targetObjName;
        this.startDate = startDate;
        this.endDate = endDate;
        this.status = status;
        this.receiveFundType = receiveFundType;
        this.paymentFundType = paymentFundType;
        this.sortType = sortType;
        this.storeId = storeId || Engine.profile?.filterStore?.id;
        this.excludeTriggeredFundOrder = excludeTriggeredFundOrder;
    }

    /** 清空筛选条件 */
    clear() {
        this.id = null;
        this.title = null;
        this.targetObjName = null;
        this.startDate = null;
        this.endDate = null;
        this.status = null;
        this.targetObjId = null;
    }

    /**
     * 克隆当前筛选条件
     * @returns {FundOrderFilter} 克隆后的新实例
     */
    static clone(filter) {
        return new FundOrderFilter({
            id: filter.id,
            title: filter.title,
            targetObjName: filter.targetObjName,
            targetObjId: filter.targetObjId,
            startDate: filter.startDate,
            endDate: filter.endDate,
            status: filter.status,
            receiveFundType: filter.receiveFundType,
            paymentFundType: filter.paymentFundType,
            sortType: filter.sortType,
            storeId: filter.storeId,
            excludeTriggeredFundOrder: filter.excludeTriggeredFundOrder
        });
    }

    /**
     * 转换为JSON对象（内部方法）
     * @param {FundOrderFilter} instance - 筛选条件实例
     * @param {boolean} [withState=false] - 是否包含状态
     * @returns {Object} JSON对象
     */
    _$FundOrderFilterToJson(instance, { withState = false } = {}) {
        const ret = {};

        if (instance.status != null && instance.status === CommonOrderStatus.WaitReview.code && withState) {
            ret['a_orderStatus'] = 0;
        }
        if (instance.status != null && instance.status === CommonOrderStatus.Passed.code && withState) {
            ret['a_orderStatus'] = 1;
        }

        if (instance.receiveFundType != null) {
            ret["b_receiptOrderType"] = instance.receiveFundType.code;
        }

        if (instance.paymentFundType != null) {
            ret["b_paymentOrderType"] = instance.paymentFundType.code;
        }

        if (instance.id != null && instance.id !== "") {
            ret["a_lke_id"] = instance.id;
        }
        if (instance.title != null && instance.title !== "") {
            ret["a_lke_orderTitle"] = instance.title;
        }
        if (instance.targetObjName != null && instance.targetObjName !== "") {
            ret["c_lke_name"] = instance.targetObjName;
        }
        if (instance.targetObjId != null && instance.targetObjId !== "") {
            ret["c_id"] = instance.targetObjId;
        }

        // 处理日期范围
        if (instance.startDate != null && instance.endDate != null &&
            instance.endDate > instance.startDate) {
            ret["a_gte_businessTime"] = DateUtil.formatDate(instance.startDate, "yyyy-MM-dd HH:mm:ss");
            ret["a_lte_businessTime"] = DateUtil.formatDate(instance.endDate, "yyyy-MM-dd HH:mm:ss");
        } else if (instance.startDate != null) {
            ret["a_gte_businessTime"] = DateUtil.formatDate(instance.startDate, "yyyy-MM-dd HH:mm:ss");
        } else if (instance.endDate != null) {
            ret["a_lte_businessTime"] = DateUtil.formatDate(instance.endDate, "yyyy-MM-dd HH:mm:ss");
        }

        // 处理排序
        if (instance.sortType === OrderSortType.CreateTime.code) {
            ret["sort"] = "a.create_time desc";
        } else if (instance.sortType === OrderSortType.OperationTime.code) {
            ret["sort"] = "a.business_time desc, a.create_time desc";
        }

        // 门店过滤
        if (instance.storeId != null) {
            ret["storeId"] = instance.storeId;
        }

        // 业务单据触发过滤
        if (instance.excludeTriggeredFundOrder === true) {
            ret["ign_excludeTriggeredOrder"] = 1;
        }

        //console.log("fund order filter:", ret);

        return ret;
    }

    /**
     * 转换为JSON对象
     * @param {boolean} [withState=false] - 是否包含状态
     * @returns {Object} JSON对象
     */
    toJson({ withState = false } = {}) {
        return this._$FundOrderFilterToJson(this, { withState });
    }
}

/// 待付款单关联信息
export class PendingPaymentOrderRelation {
    /// 关联数据id
    id = "";

    /// 待付款单 PendingPaymentOrder
    pendingOrder = null;

    /// 付款单 PaymentOrder
    paymentOrder = null;

    /// 核销金额
    _hexiaoAmount = new CsFundDouble(0);

    /// 编辑前核销金额，用于付款单编辑时本单据计算
    _hexiaoAmountBeforeEdit = new CsFundDouble(0);

    /// UI选中状态
    selected = false;

    constructor({
        id,
        pendingOrder,
        paymentOrder,
        hexiaoAmount,  // double
        hexiaoAmountBeforeEdit,
    }) {
        this.id = id;
        this.pendingOrder = pendingOrder;
        this.paymentOrder = paymentOrder;
        this.hexiaoAmount = hexiaoAmount;
        this._hexiaoAmountBeforeEdit = hexiaoAmountBeforeEdit != null ? (new CsFundDouble(hexiaoAmountBeforeEdit)) : (new CsFundDouble(0));
    }

    get hexiaoAmount() {
        return this._hexiaoAmount.value;
    }

    set hexiaoAmount(value) {
        this._hexiaoAmount = new CsFundDouble(value);
    }

    get hexiaoAmountBeforeEdit() {
        return this._hexiaoAmountBeforeEdit.value;
    }

    set hexiaoAmountBeforeEdit(value) {
        this._hexiaoAmountBeforeEdit = new CsFundDouble(value);
    }

    static clone(instance) {
        let clone = new PendingPaymentOrderRelation({
            id: instance.id,
            pendingOrder: instance.pendingOrder,
            paymentOrder: instance.paymentOrder,
            hexiaoAmount: instance.hexiaoAmount,
            hexiaoAmountBeforeEdit: instance._hexiaoAmountBeforeEdit.value
        });

        return clone;
    }

    // order PaymentOrder
    static fromJsonForPaymentOrder(json, order) {
        return new PendingPaymentOrderRelation({
            id: Util.jsonToString(json.id),
            pendingOrder: new PendingPaymentOrder({
                targetObject: new TargetObject({ objType: TargetObjectType.Unknown }),
                progressState: ProgressState.None,
                totalMount: Util.jsonToDouble(json.sumPrice, 0),
                paymentRelationOrderList: [],
                id: Util.jsonToString(json.joinOrderId),
                docCode: Util.jsonToString(json.joinOrderId),
                storeId: "", // todo check
                storeName: "", // todo check
                hexiaoAmount: Util.jsonToDouble(json.overPrice, 0),  //付款金额-审核的  待付单据核销金额
                title: Util.jsonToString(json.sourceOrderTitle),
                parentDocTitle: Util.jsonToString(json.sourceOrderTitle),
                parentDocType: OrderUtil.jsonToDocType(json.sourceOrderType, null),
                parentDocCode: Util.jsonToString(json.sourceOrderId),
                dataSource: Util.jsonToPendingPaymentFundSource(json.dataSource),
            }),
            paymentOrder: order,
            hexiaoAmount: Util.jsonToDouble(json.nowPrice, 0),  //本次核销，付款的本次核销金额
            hexiaoAmountBeforeEdit: Util.jsonToDouble(json.nowPrice, 0),
        });
    }

    // order PendingPaymentOrder
    static fromJsonForPendingPaymentOrder(json, order) {
        return new PendingPaymentOrderRelation({
            id: "",
            pendingOrder: order,
            paymentOrder: PaymentOrder.fromJson(json),
            hexiaoAmount: Util.jsonToDouble(json.nowPrice, 0),
            hexiaoAmountBeforeEdit: Util.jsonToDouble(json.nowPrice, 0)
        });
    }

    _$PendingPaymentOrderRelationToPrintJson(instance) {
        return {
            id: instance.id,
            hexiaoAmount: instance.hexiaoAmount,
            paymentOrder: instance.paymentOrder.toJson()
        };
    }

    toPrintInfoJson() {
        return this._$PendingPaymentOrderRelationToPrintJson(this);
    }
}

/// 付款单
export class PaymentOrder extends DocBase {
    constructor({
        // Required params
        targetObject,  /// 往来单位
        date,
        pendingPaymentOrderList = [], // List<PendingPaymentOrderRelation>
        disCount = 0,  // double
        fundType, // 单据类型 PaymentFundType

        // Optional params
        payAmount = null,
        /// 下级应付款信息 其他付款单应付 > 大于实付时产生的应付单据 PendingPaymentOrder
        subPendingPaymentOrder = null,
        /// 付款资金溢出处理方式 PaymentOverFlowHandleMethod
        overFlowHandleMethod = null,
        /// 付款资金账户信息 FundAccount
        account = null,
        prePaymentHexiaoMount = null,

        hexiaoMount = 0,
        hexiaoMountInSideOrder = 0,

        // /// 已审核单据预付核销金额
        prePaymentHexiaoMountOriginalForReviewedOrder = 0,

        enablePrePaymentOffset = null,

        // Super params
        id,
        storeId,
        storeName,
        remark = "",
        operator = "",
        operatorId = "",
        docMaker = "",
        status = CommonOrderStatus.WaitReview,
        title = "",
        docCode = "",
        parentDocType = null,
        parentDocCode = "",
        parentDocTitle = "",
        sourceDocType = null,
        sourceDocCode = "",
        sourceDocTitle = "",
        recordDate = null,

        //
        initWithCalcPayRelation = false  // 初始化数据类型
    }) {

        super({
            id: id,
            storeId: storeId,
            storeName: storeName,
            title: title,
            docCode: docCode,
            status: status,
            docType: DocType.FKD,
            parentDocType: parentDocType,
            parentDocCode: parentDocCode,
            parentDocTitle: parentDocTitle,
            sourceDocCode: sourceDocCode,
            sourceDocType: sourceDocType,
            sourceDocTitle: sourceDocTitle,
            recordDateTime: recordDate,
            operateDateTime: date,
            operator: operator,
            operatorId: operatorId,
            docMaker: docMaker,
            remark: remark
        });

        /// 往来单位 TargetObject
        this.targetObject = targetObject;
        /// 待付款单(单据、核销金额)
        this._pendingPaymentOrderList = pendingPaymentOrderList;
        /// 优惠金额
        this._discount = new CsFundDouble(disCount);
        /// 源核销金额 = 待付款单核销金额和
        this._hexiaoMount = new CsFundDouble(hexiaoMount);
        this._payMount = payAmount !== null ? new CsFundDouble(payAmount) : null;
        /// 单据据内核销 = 当前应付
        this._hexiaoMountInSideOrder = new CsFundDouble(hexiaoMountInSideOrder);
        /// 单据类型 PaymentFundType
        this.fundType = fundType;
        /// 付款资金账户信息
        this.fundAccount = account || new FundAccount();
        /// 付款资金溢出处理方式 PaymentOverFlowHandleMethod
        this._paymentOverFlowHandleMethod = overFlowHandleMethod;
        /// 预付款冲抵核销
        this._prePaymentHexiaoMount = prePaymentHexiaoMount;
        this._enablePrePaymentOffset = enablePrePaymentOffset ?? ((prePaymentHexiaoMount !== null && prePaymentHexiaoMount.value > 0) ||
            prePaymentHexiaoMount === null);
        this.subPendingPaymentOrder = subPendingPaymentOrder;
        /// 已审核单据预付核销金额
        /// 初始化记录时赋值
        /// 用于已审核单据编辑时，计算 targetObject 的可用预存金额
        this._prePaymentHexiaoMountOriginalForReviewedOrder = prePaymentHexiaoMountOriginalForReviewedOrder;

        /// 已有单据从为冲抵到冲抵首次变更
        this._firstTimeModifyPaymentAmountAsEnablePrePaymentOffsetChanged = true;

        this.fundAccount = !Util.isEmpty(this.fundAccount.id)
            ? this.fundAccount
            : OrderUtil.getOrderDefaultFundAccount(
                this.storeId, this.fundAccount);

        if (Engine.getOrgSettings().enableQuickFundType) {
            this._paymentOverFlowHandleMethod =
                this._paymentOverFlowHandleMethod ?? PaymentOverFlowHandleMethod.ToAccount;
        }

        if (initWithCalcPayRelation) {
            this.calculateMount();
        }
    }

    /// 已审核单据预付核销金额
    _prePaymentHexiaoMountOriginalForReviewedOrder = 0;

    /// 往来单位可用于核销金额
    /// 1. 新单或是未审核单据 金额 = 往来单位预存金额
    /// 2. 已审核单据 金额 = 往来单位预存金额 + 本次预存核销金额
    /// 注意：该项是在targetObject 没有切换情况下(目前已有单据编辑不切换targetobj)
    ///       如果以后支持targetObject 切换，需要调整 (参考采购单)
    get targetObjectPrePaymentMount() {
        return (this.targetObject.prePayment?.value || 0) +
            this._prePaymentHexiaoMountOriginalForReviewedOrder;
    }

    /// 待付款单列表   List<PendingPaymentOrderRelation>
    _pendingPaymentOrderList = [];

    /// 源核销金额 = 待付款单核销金额和
    _hexiaoMount = new CsFundDouble(0);

    /// 预付款冲抵核销 CsFundDouble
    _prePaymentHexiaoMount = null;

    /// 优惠金额
    _discount = new CsFundDouble(0);

    /// 单据据内核销 CsFundDouble
    _hexiaoMountInSideOrder = new CsFundDouble(0);

    /// 付款总金额 = 核销金额-优惠金额 - 预付冲抵
    /// 为空，则为设置，默认按上述公式计算默认值
    /// 方便用户快捷计算 CsFundDouble
    _payMount = null;

    /// 付款资金账户信息
    fundAccount = new FundAccount();

    /// 付款资金溢出处理方式
    _paymentOverFlowHandleMethod = null;

    /// 下级应付款信息 PendingPaymentOrder
    subPendingPaymentOrder = null;

    /// 使能预付冲抵
    _enablePrePaymentOffset = false;

    /// 预付款冲抵核销本身 CsFundDouble
    get prePaymentHexiaoMountOriginal() {
        return this._prePaymentHexiaoMount;
    }

    get prePaymentHexiaoMount() {
        if (this._prePaymentHexiaoMount !== null) {
            // 如果单据变更后核销金额小于0，则不再预付冲抵
            if (this._hexiaoMount.value > 0) {
                return this._prePaymentHexiaoMount.value;
            } else {
                return 0;
            }
        } else if (this._enablePrePaymentOffset && this._hexiaoMount.value > 0) {
            /// 开启预付冲抵，返回最大冲抵金额
            /// 预付冲抵核销金额为正数
            const remainWaitPayAfterDiscount = this._hexiaoMount.value - this._discount.value;
            const prePaymentAmount = this.targetObjectPrePaymentMount;
            return Math.min(prePaymentAmount, remainWaitPayAfterDiscount);
        }
        return 0;
    }

    set prePaymentHexiaoMount(value) {
        this._prePaymentHexiaoMount = new CsFundDouble(value);
        this.calculateMount();
    }

    /// 使能预付冲抵
    get enablePrePaymentOffset() {
        return this._enablePrePaymentOffset;
    }

    set enablePrePaymentOffset(value) {
        // 变更冲抵本身参数
        if (value != this._enablePrePaymentOffset) {
            this._prePaymentHexiaoMount = null;
        }

        this._enablePrePaymentOffset = value;
    }

    /*
    set enablePrePaymentOffset(value) {
        // 值未改变
        if (this._enablePrePaymentOffset == value) return;

        // step 1 已有单据，并且未变更过, 进行已有单据冲抵变更
        if (Util.isEmpty(this.id) &&
            this._firstTimeModifyPaymentAmountAsEnablePrePaymentOffsetChanged) {
            this._firstTimeModifyPaymentAmountAsEnablePrePaymentOffsetChanged = false;

            // 从非冲抵到冲抵(注意：金额变更以核销金额为准):
            // 1. 如果付款金额正好等于核销金额，设定paymentMount为空, 进入自动计算模式
            // 2. 如果付款金额不等于核销金额，付款扣除冲抵金额，保持手动计算模式
            if (value && this._payMount != null) {
                if (this._payMount.value == hexiaoMount) {
                    this._payMount = null;
                } else {
                    this.payMount = this._payMount.value - hexiaoMount;
                }
            }
            // 从冲抵到非冲抵（注意：金额变更以冲抵金额为准）:
            // 1. 如果付款金额正好等于0，设定paymentMount为空, 进入自动计算模式
            // 2. 如果付款金额不等于核销金额，增加付款金额=冲抵金额，保持手动计算模式
            else if (!this.value && this._payMount != null && this._prePaymentHexiaoMount != null) {
                if (this._payMount.value == 0) {
                    this._payMount = null;
                } else {
                    this.payMount = this._payMount.value + this._prePaymentHexiaoMount;
                }
            }
        }

        // step 2 变更冲抵本身参数
        if (value != this._enablePrePaymentOffset) {
            this._prePaymentHexiaoMount = null;
        }

        this._enablePrePaymentOffset = value;
    }
    */

    get overflowMount() {
        return new CsFundDouble(this.payMount - (this.hexiaoMount - this.discount - this.prePaymentHexiaoMount)).value;
    }

    /// 实际付款 = 付款金额 + 预付冲抵 - 预存
    get actualPayMount() {
        let value = this.payMount + this.prePaymentHexiaoMount;
        if (this.overflowMount > 0 &&
            this._paymentOverFlowHandleMethod !== null &&
            this._paymentOverFlowHandleMethod.code !== PaymentOverFlowHandleMethod.ToAccount.code) {
            value -= this.overflowMount;
        }
        return value;
    }

    /// 剩余待付金额
    get remainMount() {
        return this._hexiaoMount.value - this._discount.value - this.payMount - this.prePaymentHexiaoMount;
    }

    /// 单据据内核销 = 当前应付
    get hexiaoMountInSideOrder() {
        return this._hexiaoMountInSideOrder.value;
    }

    /// 单据据内核销
    set hexiaoMountInSideOrder(value) {
        this._hexiaoMountInSideOrder = new CsFundDouble(value);
        this.calculateMount();
    }

    get hexiaoMount() {
        return this._hexiaoMount.value;
    }

    set hexiaoMount(value) {
        this._hexiaoMount = new CsFundDouble(value);
        this.calculateMount();
    }

    /// 付款总金额 = 核销金额-优惠金额 - 预付冲抵
    /// 为空，则为设置，默认按上述公式计算默认值
    /// 方便用户快捷计算
    get payMount() {
        return this._payMount !== null
            ? this._payMount.value
            : (this._hexiaoMount.value - this._discount.value - this.prePaymentHexiaoMount);
    }

    set payMount(value) {
        this._payMount = new CsFundDouble(value);
    }

    // 返回未计算的 payMount
    get payMountOriginal() { return this._payMount; }



    get discount() {
        return this._discount.value;
    }

    set discount(value) {
        this._discount = new CsFundDouble(value);
        this.calculateMount();
    }

    /// 待付款单列表 PendingPaymentOrder
    get pendingPaymentOrderList() {
        return this._pendingPaymentOrderList.map(element => element.pendingOrder);
    }

    /// 待付款单关联列表 PendingPaymentOrderRelation
    get pendingPaymentOrderRelationList() {
        return [...this._pendingPaymentOrderList];
    }

    /// 付款资金溢出处理方式 PaymentOverFlowHandleMethod
    get paymentOverFlowHandleMethod() {
        return this._paymentOverFlowHandleMethod;
    }

    /// 付款资金溢出处理方式 PaymentOverFlowHandleMethod
    set paymentOverFlowHandleMethod(value) {
        this._paymentOverFlowHandleMethod = value;
    }

    /**
     * 更新待付款单核销金额
     * @param {string} pendingOrderId - 待付款单ID
     * @param {number} value - 核销金额
     * @param {number} hexiaoAmountBeforeEidt - 编辑前的核销金额
     * @returns {boolean} - 是否更新成功
     */
    updatePendingOrderHeXiaoValue(pendingOrderId, value, { hexiaoAmountBeforeEidt = 0 } = {}) {
        if (value === 0) return false;

        let entry = null;

        for (const element of this._pendingPaymentOrderList) {
            if (element.pendingOrder.id === pendingOrderId) {
                entry = element;
                break;
            }
        }

        // 付款退款单
        if (this.fundType.code === PaymentFundType.FKTK.code) {
            if (entry === null ||
                new CsFundDouble(value).value >
                -(new CsFundDouble(entry.pendingOrder.pendingPayMount + hexiaoAmountBeforeEidt).value)) {
                return false;
            }
        }
        // 付款单中含有应付款退款单
        else if (entry !== null && entry.pendingOrder.totalMount < 0) {
            if (value > 0 ||
                Math.abs(new CsFundDouble(value).value) >
                Math.abs(new CsFundDouble(entry.pendingOrder.pendingPayMount + hexiaoAmountBeforeEidt).value)) {
                return false;
            }
        }
        else if (entry === null ||
            new CsFundDouble(value).value >
            new CsFundDouble(entry.pendingOrder.pendingPayMount + hexiaoAmountBeforeEidt).value) {
            return false;
        }

        // 添加了精度格式，注意是否引起问题
        if (this.fundType.code === PaymentFundType.FKTK.code) {
            // 付款退款为负数
            entry.hexiaoAmount = new CsFundDouble(-value).value;
        } else {
            entry.hexiaoAmount = new CsFundDouble(value).value;
        }
        // 注意该代码是否会引起问题
        entry.hexiaoAmountBeforeEdit = hexiaoAmountBeforeEidt;
        this.calculateMount();
        return true;
    }

    /**
     * 验证并更新待付款单核销金额
     * @param {string} pendingOrderId - 待付款单ID
     * @param {number} value - 核销金额
     * @param {number} hexiaoAmountBeforeEidt - 编辑前的核销金额
     * @returns {string|null} - 错误消息，null表示验证通过
     */
    validateAndUpdatePendingOrderHeXiaoValue(pendingOrderId, value, { hexiaoAmountBeforeEidt = 0 } = {}) {
        if (value === 0) {
            return "核销金额不能为0";
        }

        let entry = null;
        for (const element of this._pendingPaymentOrderList) {
            if (element.pendingOrder.id === pendingOrderId) {
                entry = element;
                break;
            }
        }

        if (entry === null) {
            return "待付单据不存在";
        }

        // 核销后为正数，付款就为正数
        // 核销后为负数，付款就为负数
        // 通过乘法判断
        if ((entry.pendingOrder.pendingPayMount + hexiaoAmountBeforeEidt) * value < 0) {
            return (entry.pendingOrder.pendingPayMount + hexiaoAmountBeforeEidt) > 0
                ? "核销金额应大于0"
                : "核销金额应小于0";
        }

        // 付款退款单
        if (this.fundType.code === PaymentFundType.FKTK.code) {
            if (new CsFundDouble(value).value >
                -new CsFundDouble(entry.pendingOrder.pendingPayMount + hexiaoAmountBeforeEidt).value) {
                return "核销金额超过待付金额";
            }
        }
        // 付款单中含有应付款退款单
        else if (entry.pendingOrder.totalMount < 0) {
            if (value > 0 ||
                Math.abs(new CsFundDouble(value).value) >
                Math.abs(new CsFundDouble(entry.pendingOrder.pendingPayMount + hexiaoAmountBeforeEidt).value)) {
                return "核销金额超过待付金额";
            }
        }
        else if (new CsFundDouble(value).value >
            new CsFundDouble(entry.pendingOrder.pendingPayMount + hexiaoAmountBeforeEidt).value) {
            return "核销金额超过待付金额";
        }

        // 添加了精度格式，注意是否引起问题
        if (this.fundType.code === PaymentFundType.FKTK.code) {
            // 付款退款为负数
            entry.hexiaoAmount = new CsFundDouble(-value).value;
        } else {
            entry.hexiaoAmount = new CsFundDouble(value).value;
        }

        // 注意该代码是否会引起问题
        entry.hexiaoAmountBeforeEdit = hexiaoAmountBeforeEidt;
        this.calculateMount();
        return null;
    }

    /**
     * 校验优惠金额
     * @param {number} discountPrice - 优惠金额
     * @returns {string|null} - 错误消息，null表示验证通过
     */
    validateDiscountPrice(discountPrice) {
        if (discountPrice * this._hexiaoMount.value < 0) {
            return this._hexiaoMount.value > 0
                ? "优惠金额应大于等于0"
                : "优惠金额应小于等于0";
        }

        if (Math.abs(discountPrice) > Math.abs(this._hexiaoMount.value)) {
            return "优惠金额不能超过核销总金额";
        }
        return null;
    }

    /**
     * 校验付款金额
     * @param {number} payMount - 付款金额
     * @returns {string|null} - 错误消息，null表示验证通过
     */
    validatePayMount(payMount) {
        if (payMount * this._hexiaoMount.value < 0) {
            return this._hexiaoMount.value > 0
                ? "付款金额应大于等于0"
                : "付款金额应小于等于0";
        }
        return null;
    }

    /**
     * 校验预付核销
     * @returns {string|null} - 错误消息，null表示验证通过
     */
    _validatePrePaymentHexiaoMount() {
        if (this.prePaymentHexiaoMount < 0) {
            return "预付冲抵金额不能小于0";
        }
        else if (this.prePaymentHexiaoMount !== 0 &&
            this.prePaymentHexiaoMount > this._hexiaoMount.value) {
            return "预付冲抵金额不能超过核销金额";
        }
        return null;
    }

    // 校验单据合法性
    validateOrder() {

        // 预付冲抵校验
        let ret = this._validatePrePaymentHexiaoMount();

        if (ret) {
            return { msgBoxConfirm: true, errorMsg: ret }
        }

        // 需要核销单据金额校验
        for (const element
            of this._pendingPaymentOrderList) {
            if (element.hexiaoAmount == 0) {
                let index = this._pendingPaymentOrderList.indexOf(element);
                if (!Util.isEmpty(element.pendingOrder.parentDocTitle)) {
                    return { msgBoxConfirm: true, errorMsg: `第${index}张应付单 \"${element.pendingOrder.parentDocTitle}\" 核销金额为 0, 请设置核销金额!` }
                } else {
                    return { msgBoxConfirm: true, errorMsg: `第${index}张应付单核销金额为 0, 请设置核销金额!` }
                }
            }
        }

        // 付款金额溢出选项
        if (this.payMount >
            (new CsFundDouble(this.hexiaoMount -
                this.discount -
                this.prePaymentHexiaoMount))
                .value &&
            this.paymentOverFlowHandleMethod == null) {                                                    
            return { msgBoxConfirm: true, errorMsg: `付款金额有余额 ${new CsFundDouble(this.payMount - (this.hexiaoMount - this.discount - this.prePaymentHexiaoMount)).value}: \n付款金额${this.payMount}大于 核销金额${this.hexiaoMount} 减去 优惠金额${this.discount} 和 预付冲抵金额${this.prePaymentHexiaoMount}。\n\n 处理方式: \n 1 核对付款金额，确认是否正确 \n 2 如果有余额，请选择付款余额处理方式后再提交!` };
        }

        // 付款不足 （ hexiaoMount = 0, 直接付，退款，不用判断）
        if (this.hexiaoMount > 0) {
            if (this.payMount <
                (new CsFundDouble(this.hexiaoMount -
                    this.discount -
                    this.prePaymentHexiaoMount))
                    .value) {

                return { msgBoxConfirm: true, errorMsg: "付款金额应大于或等于 核销金额 减去 优惠金额 以及 预付冲抵金额，请调整付款金额" };
            }
        } else if (this.hexiaoMount < 0) {
            if (this.payMount >
                (new CsFundDouble(this.hexiaoMount -
                    this.discount -
                    this.prePaymentHexiaoMount))
                    .value) {

                return { msgBoxConfirm: true, errorMsg: "付款(退款)金额应小于或等于 核销金额 减去 优惠金额，请调整付款金额!" };
            }
        }

        // 核销和支付金额为0，核查是否有退款核销，否则报错
        if (this.payMount == 0 && this.hexiaoMount == 0) {
            let zeroHexiaoAmount = true;
            for (let i = 0;
                i < this.pendingPaymentOrderRelationList.length;
                i++) {
                if (this.pendingPaymentOrderRelationList[i]
                    .hexiaoAmount != 0) {
                    zeroHexiaoAmount = false;
                    break;
                }
            }

            if (zeroHexiaoAmount) {
                return { msgBoxConfirm: true, errorMsg: "请选择核销单据以及付款金额!" };

            }
        }

        return null;

    }


    /// 空构造函数
    static empty({
        fundType,
        operator = "",
        operatorId = "",
        storeId = null,
        storeName = null,
        payAmount = null,
        overFlowHandleMethod = null, // PaymentOverFlowHandleMethod
        account = null, // FundAccount
        prePaymentHexiaoAmount = null
    }) {
        return new PaymentOrder({
            targetObject: new TargetObject({ objType: TargetObjectType.Unknown }),
            date: new Date(),
            pendingPaymentOrderList: [],
            disCount: 0,
            fundType: fundType,
            payAmount: payAmount,
            overFlowHandleMethod: overFlowHandleMethod,
            account: account,
            prePaymentHexiaoMount: prePaymentHexiaoAmount,
            id: "",
            storeId: storeId,
            storeName: storeName,
            operator: operator,
            operatorId: operatorId
        });
    }

    /// 拷贝
    static clone(order) {

        let baseOrder = DocBase.clone(order);

        const cloned = new PaymentOrder({
            targetObject: TargetObject.clone(order.targetObject),
            disCount: order.discount,
            pendingPaymentOrderList: order._pendingPaymentOrderList.map(e => PendingPaymentOrderRelation.clone(e)),
            payAmount: order._payMount?.value,
            hexiaoAmount: order._hexiaoMount.value,
            fundType: order.fundType,
            hexiaoMountInSideOrder: order._hexiaoMountInSideOrder.value,
            account: order.fundAccount,
            overFlowHandleMethod: order._paymentOverFlowHandleMethod,
            prePaymentHexiaoMount: order._prePaymentHexiaoMount?.value,
            subPendingPaymentOrder: order.subPendingPaymentOrder,
            enablePrePaymentOffset: order._enablePrePaymentOffset,
            prePaymentHexiaoMountOriginalForReviewedOrder:
                order._prePaymentHexiaoMountOriginalForReviewedOrder,
        });


        Object.assign(cloned, baseOrder);

        return cloned;
    }

    /// 计算金额
    calculateMount() {
        this._hexiaoMount = new CsFundDouble(0);

        for (const element of this._pendingPaymentOrderList) {
            this._hexiaoMount = this._hexiaoMount.add(new CsFundDouble(element.hexiaoAmount));
        }

        // 添加 CsFundDouble 解决累计运算后精度问题 todo 需要测试有没有问题
        if (this.fundType.code === PaymentFundType.FKTK.code) {
            this._hexiaoMount = new CsFundDouble(this._hexiaoMount.value);
            if (this._hexiaoMount.value < 0) {
                this._hexiaoMount = this._hexiaoMount.multiply(-1);
            }
        }

        if ([PaymentFundType.YFD.code, PaymentFundType.YFZ.code, PaymentFundType.FKTK.code].includes(this.fundType.code)) {
            this._payMount = this._hexiaoMount
                .add(this._hexiaoMountInSideOrder)
                .sub(this._discount)
                .sub(new CsFundDouble(this.prePaymentHexiaoMount));
        }
    }

    /**
 * 清空付款单数据
 */
    clear() {
        this._pendingPaymentOrderList = [];
        this._hexiaoMount = new CsFundDouble(0);
        this._payMount = null;
        this._discount = new CsFundDouble(0);
        this._prePaymentHexiaoMount = null;
    }

    /**
     * 获取指定待支付单的核销金额
     * @param {string} pendingPaymentId - 待支付单ID
     * @returns {number} - 核销金额
     */
    getPendingPaymentCount(pendingPaymentId) {
        let payValue = 0;

        for (const element of this._pendingPaymentOrderList) {
            if (element.pendingOrder.id === pendingPaymentId) {
                payValue = element.hexiaoAmount;
                break;
            }
        }

        return payValue;
    }

    /**
     * 更新关联的待支付单列表
     * @param {PendingPaymentOrderRelation[]} orderList - 新的待支付单列表
     */
    updatePendingPaymentOrderList(orderList) {
        this._pendingPaymentOrderList = orderList;
        this.calculateMount();
    }

    /**
     * 移除指定的待支付单
     * @param {Object.<string, boolean>} orderMap - 待移除的订单ID映射
     */
    removePendingPaymentOrder(orderMap) {
        Object.keys(orderMap).forEach(removeId => {
            if (orderMap[removeId]) {
                this._pendingPaymentOrderList = this._pendingPaymentOrderList.filter(
                    element => element.pendingOrder.id !== removeId
                );
            }
        });

        // 如果列表为空则重置相关金额 todo 后续根据情况更新
        if (this._pendingPaymentOrderList.length === 0) {
            this._discount = new CsFundDouble(0);
            this._prePaymentHexiaoMount = null;
        }

        this.calculateMount();
    }

    /**
     * 添加待支付单，如果是重复添加就会覆盖key, 保留value
     * orderBeforeEdit 编辑单据是，编辑前原据，用于原单据删除核销应付单，然后再次添加
     * 而此时核销金额不能涵盖之前草稿单据时已核销的部分
     * @param {PendingPaymentOrder[]} orderList - 要添加的订单列表
     * @param {Object} [options] - 选项
     * @param {PaymentOrder} [options.orderBeforeEdit] - 编辑前的订单
     * @param {boolean} [options.hexiaoAll=true] - 是否核销全部金额
     */
    addPendingPaymentOrder(orderList, { orderBeforeEdit = null, hexiaoAll = true } = {}) {
        const tmpList = [];

        console.log("addPendingPaymentOrder", orderList);

        for (const element of orderList) {
            let entry = null;

            // 检查当前列表中是否已存在
            for (const item of this._pendingPaymentOrderList) {
                if (item.pendingOrder.id === element.id) {
                    entry = item;
                    tmpList.push(item);
                    break;
                }
            }

            // 检查编辑前的订单中是否存在  之前草稿单据编辑
            if (!entry && orderBeforeEdit) {
                for (const item of orderBeforeEdit._pendingPaymentOrderList) {
                    if (item.pendingOrder.id === element.id) {
                        entry = item;
                        tmpList.push(item);
                        break;
                    }
                }
            }

            // 新增条目
            if (!entry) {
                tmpList.push(new PendingPaymentOrderRelation({
                    id: "",
                    pendingOrder: element,
                    paymentOrder: this,
                    hexiaoAmount: hexiaoAll ? element.pendingPayMount : 0
                }));
            }
        }

        this._pendingPaymentOrderList = tmpList;
        this.calculateMount();
    }

    // 以下为静态权限检查方法
    static hasReadPermission() {
        return Engine.profile.permissionMgr.hasPermission([
            FunctionPermissionDefinition.P_DealingPayment_Read,
            FunctionPermissionDefinition.P_DealingPayment_Edit,
            FunctionPermissionDefinition.P_DealingPayment_Audit,
        ]);
    }

    static hasEditPermission() {
        if (Engine.getOrgSettings().enableQuickFundType) {
            return Engine.profile.permissionMgr.hasPermission([
                FunctionPermissionDefinition.P_DealingPayment_Edit,
                FunctionPermissionDefinition.P_DealingPayment_Audit,
            ]);
        }
        return Engine.profile.permissionMgr.hasPermission([
            FunctionPermissionDefinition.P_DealingPayment_Edit,
        ]);
    }

    static hasAuditPermission() {
        if (Engine.getOrgSettings().enableQuickFundType) {
            return Engine.profile.permissionMgr.hasPermission([
                FunctionPermissionDefinition.P_DealingPayment_Edit,
                FunctionPermissionDefinition.P_DealingPayment_Audit
            ]);
        }
        return Engine.profile.permissionMgr.hasPermission([
            FunctionPermissionDefinition.P_DealingPayment_Audit
        ]);
    }

    static hasPrePaymentEditPermission() {
        if (Engine.getOrgSettings().enableQuickFundType) {
            // 快捷模式下，编辑和审核同等权利
            return Engine.profile.permissionMgr.hasPermission([
                FunctionPermissionDefinition.P_AccountPrePayment_Edit,
                FunctionPermissionDefinition.P_AccountPrePayment_Audit,
                FunctionPermissionDefinition.P_DealingPayment_Edit,
                FunctionPermissionDefinition.P_DealingPayment_Audit
            ]);
        }
        return Engine.profile.permissionMgr.hasPermission([
            FunctionPermissionDefinition.P_AccountPrePayment_Edit,
            FunctionPermissionDefinition.P_DealingPayment_Edit,
        ]);
    }

    static hasPrePaymentAuditPermission() {
        if (Engine.getOrgSettings().enableQuickFundType) {
            // 快捷模式下，编辑和审核同等权利
            return Engine.profile.permissionMgr.hasPermission([
                FunctionPermissionDefinition.P_AccountPrePayment_Edit,
                FunctionPermissionDefinition.P_AccountPrePayment_Audit,
                FunctionPermissionDefinition.P_DealingPayment_Edit,
                FunctionPermissionDefinition.P_DealingPayment_Audit
            ]);
        }
        return Engine.profile.permissionMgr.hasPermission([
            FunctionPermissionDefinition.P_AccountPrePayment_Audit,
            FunctionPermissionDefinition.P_DealingPayment_Audit
        ]);
    }

    /**
     * 将付款退款单转换为采购付款单
     * @returns {PaymentOrder} - 转换后的付款单
     */
    convertFKTK2CGFK() {
        const sktkOrder = this;
        const order = PaymentOrder.clone(sktkOrder);
        order._discount = new CsFundDouble(-sktkOrder._discount.value);
        order.payMount = -sktkOrder.payMount;
        order._hexiaoMount = new CsFundDouble(-sktkOrder._hexiaoMount.value);
        order.fundType = PaymentFundType.CGFK;
        return order;
    }

    /**
     * 从JSON创建付款单实例
     * @param {Object} json - JSON数据
     * @returns {PaymentOrder} - 创建的付款单实例
     */
    static fromJson(json) {

        const baseOrder = DocBase.fromJson(json, DocType.FKD);

        const instance = new PaymentOrder({
            targetObject: json.objId == null
                ? new TargetObject({ objType: TargetObjectType.Unknown })
                : TargetObject.fromJsonForOrders(json),
            pendingPaymentOrderList: [],
            discount: Util.jsonToDouble(json.discountPrice, 0),
            hexiaoMount: Util.jsonToDouble(json.offPrice, 0),
            hexiaoMountInSideOrder: Util.jsonToDouble(json.offPriceInOrder, 0),
            payAmount: Util.jsonToDouble(json.paymentPrice, 0),
            fundType: Util.jsonToPaymentFundType(json.paymentOrderType, PaymentFundType.CGFK),
            account: new FundAccount({
                id: Util.jsonToString(json.fundAccountId),
                name: Util.jsonToString(json.fundAccountName),
                balance: 0,
                bankName: "",
                income: 0,
                expenses: 0
            }),
            overFlowHandleMethod: Util.jsonToPaymentOverFlowHandleMethod(json.overflowHandleMethod),
            prePaymentHexiaoMount: Util.jsonToCsFundDouble(json.prePaymentHexiaoMount, 0),
            // enablePrePaymentOffset: false, todo 这个构造函数有判断，但是dart 代码直接设置了值
            subPendingPaymentOrder: json.subWaitPaymentOrder
                ? PendingPaymentOrder.fromJson(json.subWaitPaymentOrder)
                : null
        });

        Object.assign(instance, baseOrder);

        // 核销使能根据核销金额更新
        instance._enablePrePaymentOffset = instance._prePaymentHexiaoMount.value > 0;

        // 初始预存核销金额,仅reviewed记录有效
        if (instance.status.code === CommonOrderStatus.Passed.code) {
            instance._prePaymentHexiaoMountOriginalForReviewedOrder =
                instance._prePaymentHexiaoMount.value;
        }

        // 处理明细数据
        const paymentDetail = json.details || [];
        instance._pendingPaymentOrderList = paymentDetail.map(element =>
            PendingPaymentOrderRelation.fromJsonForPaymentOrder(element, instance)
        );

         console.log("PaymentOrder.fromJson", instance);

        return instance;
    }

    /**
     * 转换为JSON对象(内部方法)
     * @param {PaymentOrder} instance - 付款单实例
     * @returns {Object} - JSON对象
     */
    _$PaymentOrderToJson(instance) {
        const ret = super.toJson();

        ret.paymentDetail = instance._pendingPaymentOrderList.map(element => ({
            id: element.id,
            joinOrderId: element.pendingOrder.id,
            nowPrice: element.hexiaoAmount,
            paymentId: instance.id
        }));

        ret.discountPrice = instance._discount.value;
        ret.objId = instance.targetObject.id;
        ret.offPrice = instance._hexiaoMount.value;
        ret.paymentOrderType = instance.fundType.code;
        ret.offPriceInOrder = instance._hexiaoMountInSideOrder.value;
        ret.prePaymentHexiaoMount = instance.prePaymentHexiaoMount;
        ret.paymentPrice = instance.payMount;
        ret.fundAccountId = instance.fundAccount.id;

        if (instance.paymentOverFlowHandleMethod != null) {
            ret.overflowHandleMethod = instance.paymentOverFlowHandleMethod.code;
        }

        return ret;
    }

    /**
     * 转换为JSON对象
     * @returns {Object} - JSON对象
     */
    toJson() {
        return this._$PaymentOrderToJson(this);
    }

    /**
     * 转换为打印信息JSON(内部方法)
     * @param {PaymentOrder} instance - 付款单实例
     * @returns {Object} - JSON对象
     */
    _$toPrintInfoJson(instance) {
        const ret = {};

        ret.paymentDetails = instance._pendingPaymentOrderList.map(element => ({
            paymentId: instance.id,
            id: element.id,
            hexiaoAmount: element.hexiaoAmount,
            pendingPaymentOrder: element.pendingOrder.toPrintInfoJson()
        }));

        ret.businessTime = DateUtil.getDateTimeTitle(instance.operateDate);
        ret.createUser = Engine.profile.nickName || Engine.profile.userName;
        ret.discountPrice = instance._discount.value;
        ret.handleUserId = instance.operatorId;
        ret.handleUserName = instance.operator;
        ret.id = instance.id;
        ret.offPrice = instance._hexiaoMount.value;
        ret.orderStatus = CommonOrderStatus.values.indexOf(instance.status);
        ret.orderTitle = instance.title;
        ret.orderType = DocType.values.indexOf(instance.docType);
        ret.orgId = Engine.profile.org.orgId;
        ret.fundAccount = instance.fundAccount.toJson();
        ret.overflowHandleMethod = instance.paymentOverFlowHandleMethod;
        ret.paymentPrice = instance.payMount;
        ret.updateUser = instance.updateor;
        ret.targetObj = instance.targetObject.toPrintInfoJson();
        ret.subPendingPaymentOrder = instance.subPendingPaymentOrder?.toPrintInfoJson() || null;
        ret.remark = instance.remark;

        return ret;
    }

    /**
     * 转换为打印信息JSON
     * @returns {Object} - JSON对象
     */
    toPrintInfoJson() {
        return this._$toPrintInfoJson(this);
    }
}